home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / connx-1.0 / client.c next >
C/C++ Source or Header  |  1995-07-05  |  6KB  |  317 lines

  1. /*
  2.  * client main loop for connX
  3.  */
  4.  
  5. #include <pwd.h>
  6. #include "commun.h"
  7. #include <stdio.h>
  8. #include "connect.h"
  9. #include <strings.h>
  10. #include "xconnect.h"
  11. #include <errno.h>
  12. #include <sys/types.h>
  13. #include <sys/time.h>
  14.  
  15. #ifdef AIX
  16. #include <sys/select.h>
  17. #endif
  18.  
  19. #define CHECK_RC(rc) if (rc==-1) { printf("Server exited\n"); client_exit(); }
  20.  
  21. #define NUM_FLAGS 3
  22. enum
  23.   {
  24.     F_NAME, F_DISPLAY, F_HOST
  25.   };
  26. int flags_val[] =
  27. {F_NAME, F_DISPLAY, F_HOST};
  28. char *flags_txt[] =
  29. {"-name", "-display", "-host"};
  30.  
  31. /*prototypes */
  32. void usage (char *prog);
  33. int parse_args (int argc, char **argv, char **pName, char **pDisplay_name,
  34.         char **pHost);
  35. void play_games ();
  36. void connect_to_server (char *pName);
  37. int to_flag (char *string);
  38. void client_exit ();
  39.  
  40. /*globals*/
  41. int fd;
  42. char *program_name;
  43.  
  44. /*****************************************************************************/
  45.  
  46. main (int argc, char **argv)
  47. {
  48.   int rc;
  49.   char *pDisplay_name = NULL;
  50.   char *pName = NULL;
  51.   char *pHost = NULL;
  52.   struct passwd *pInfo;
  53.   char host[80];
  54.  
  55.   if (parse_args (argc, argv, &pName, &pDisplay_name, &pHost) == -1)
  56.     {
  57.       usage (argv[0]);
  58.       exit (1);
  59.     }
  60.  
  61.   program_name = argv[0];
  62.   if (X_open (pDisplay_name) == -1)
  63.     exit (1);
  64.  
  65. #ifdef TCPIP
  66.   if (pHost == NULL)        /* use local host */
  67.     {
  68.       gethostname (host, 80);
  69.       printf("Using %s as host\n",host);
  70.       pHost = host;
  71.     }
  72. #endif
  73.  
  74.   rc = client_open_connection (&fd, pHost);
  75.   if (rc != 0)
  76.     {
  77.       printf ("Can\'t connect\n");
  78.       exit (1);
  79.     }
  80.  
  81.   /* get default player name = userid */
  82.   if (pName == NULL)
  83.     {
  84.       pInfo = getpwuid (getuid ());
  85.       pName = pInfo->pw_name;
  86.     }
  87.   connect_to_server (pName);
  88.   play_games ();
  89. }
  90.  
  91. /****************************************************************************/
  92. /* internals ***************************************************************/
  93. /**************************************************************************/
  94.  
  95. /*
  96.  * send connection message to server
  97.  */
  98. void 
  99. connect_to_server (char *pName)
  100. {
  101.   new_player new_p;
  102.   int rc;
  103.  
  104.   strcpy (new_p.name, pName);
  105.   rc = send_message (&fd, NEW_PLAYER, sizeof (new_player), (char *) &new_p);
  106.   CHECK_RC (rc);
  107. }
  108.  
  109. /***********************************************************************/
  110.  
  111. /*
  112.  * play games of connX - exit when server exits or player selects quit
  113.  */
  114. void 
  115. play_games ()
  116.  
  117. {
  118.   gen_msg msg_recv;
  119.   game_start *start;
  120.   char data[MAX_DATA];
  121.   int my_num;
  122.   my_move mymove;
  123.   my_move *mymove_resp;
  124.   others_move *othersmove;
  125.   game_end *game_over;
  126.   int rc, num;
  127.   struct fd_set readfs;
  128.   struct timeval notimeout;
  129.   whose_move *whose;
  130.  
  131.   msg_recv.msg = (char *) &data;
  132.   notimeout.tv_sec = 0;
  133.   notimeout.tv_usec = 0;
  134.  
  135.  
  136.   while (1)
  137.  
  138.     {
  139.       FD_ZERO (&readfs);
  140.       FD_SET (fd, &readfs);
  141.  
  142.       /* handle expose, resize */
  143.       if (X_handle_events () == QUIT)
  144.     client_exit ();
  145.  
  146.       /* has to be non blocking to handle X-events */
  147.       if ((num = select (fd + 1, &readfs, NULL, NULL, ¬imeout)) < 0)
  148.     {
  149.       printf ("select error\n");
  150.       exit (1);
  151.     }
  152.  
  153.       if (num > 0)
  154.     {            /* handle incoming message */
  155.  
  156.       rc = read_message (&fd, &msg_recv);
  157.       CHECK_RC (rc);
  158.  
  159.       switch (msg_recv.msg_type)
  160.         {
  161.         case GAME_START:
  162.           start = (game_start *) msg_recv.msg;
  163.           my_num = start->your_number;
  164.           X_allocate (*start);
  165.           break;
  166.         case YOUR_MOVE:
  167.           rc = X_get_player_move (&mymove.move);
  168.           if (rc == QUIT)
  169.         client_exit ();
  170.           if (rc == FORFEIT)
  171.         {
  172.           mymove.move.row = FORFEIT;
  173.           mymove.move.column = FORFEIT;
  174.         }
  175.           rc = send_message (&fd, MY_MOVE, sizeof (mymove), (char *) &mymove);
  176.           CHECK_RC (rc);
  177.           break;
  178.         case MY_MOVE:
  179.           mymove_resp = (my_move *) msg_recv.msg;
  180.           if (mymove_resp->rc == -1)
  181.         X_bad_move ();
  182.           else
  183.         X_add_to_board (mymove_resp->move, my_num);
  184.           break;
  185.         case OTHERS_MOVE:
  186.           othersmove = (others_move *) msg_recv.msg;
  187.           if (othersmove->player_number != my_num)
  188.         X_add_to_board (othersmove->move, othersmove->player_number);
  189.           break;
  190.         case WHOSE_MOVE:
  191.           whose = (whose_move *) msg_recv.msg;
  192.           X_show_turn (whose->player);
  193.           break;
  194.         case GAME_END:
  195.           game_over = (game_end *) msg_recv.msg;
  196.           X_game_end (game_over->winner, game_over->connect[0],
  197.               game_over->connect[1]);
  198.           break;
  199.         default:
  200.           printf ("Comm problem %d\n", msg_recv.msg_type);
  201.           exit (1);
  202.         }
  203.     }
  204.     }
  205. }
  206.  
  207. /*************************************************************************/
  208.  
  209.  
  210. /* command line processing */
  211. int 
  212. parse_args (int argc, char **argv, char **pName, char **pDisplay_name,
  213.         char **pHost)
  214. {
  215.   int i;
  216.   int flag;
  217.   if (((argc - 1) % 2) != 0)
  218.     return -1;
  219.   for (i = 1; i < argc; i = i + 2)
  220.     {
  221.       flag = to_flag (argv[i]);
  222.       switch (flag)
  223.     {
  224.     case F_DISPLAY:
  225.       *pDisplay_name = argv[i + 1];
  226.       break;
  227.     case F_NAME:
  228.       *pName = argv[i + 1];
  229.       break;
  230.     case F_HOST:
  231.       *pHost = argv[i + 1];
  232.       break;
  233.     default:
  234.       return -1;
  235.     }
  236.     }
  237.  
  238.   return 0;
  239. }
  240.  
  241. /*****************************************************************************/
  242.  
  243. int 
  244. to_flag (char *string)
  245. {
  246.   int i;
  247.  
  248.   for (i = 0; i < NUM_FLAGS; i++)
  249.     if (strcmp (string, flags_txt[i]) == 0)
  250.       return flags_val[i];
  251.   return -1;
  252. }
  253.  
  254. /**************************************************************************/
  255.  
  256. void 
  257. usage (char *prog)
  258. {
  259.   int i;
  260.   printf ("Usage: %s \n", prog);
  261.   printf ("-name <player_name>\n");
  262.   printf ("-display <display>\n");
  263.   printf ("-host <host>\n\n\n");
  264. }
  265.  
  266.  
  267. /********************************************************************/
  268.  
  269. /*
  270.  * check if server cancelled move
  271.  * Note: if server cancels game, next message on queue indicates so
  272.  */
  273. int 
  274. move_cancelled ()
  275. {
  276.   int rc;
  277.   gen_msg msg_recv;
  278.   struct fd_set readfs;
  279.   struct timeval notimeout;
  280.   char data[MAX_DATA];
  281.  
  282.   msg_recv.msg = (char *) &data;
  283.   notimeout.tv_sec = 0;
  284.   notimeout.tv_usec = 0;
  285.  
  286.   FD_ZERO (&readfs);
  287.   FD_SET (fd, &readfs);
  288.  
  289.   if (select (fd + 1, &readfs, NULL, NULL, ¬imeout) > 0)
  290.     {
  291.       rc = read_message (&fd, &msg_recv);
  292.       CHECK_RC (rc);
  293.  
  294.       if (msg_recv.msg_type == CANCEL_MOVE)
  295.     /* cancelled */
  296.     return 1;
  297.     }
  298.  
  299.   /* not cancelled */
  300.   return 0;
  301.  
  302. }
  303.  
  304. /***********************************************************************/
  305.  
  306. /*
  307.  * terminate client
  308.  */
  309. void 
  310. client_exit ()
  311. {
  312.   X_deallocate ();
  313.   X_close ();
  314.   close (fd);
  315.   exit (0);
  316. }
  317.